package com.lifeonwalden.dsg.bean;

import com.lifeonwalden.dsg.constant.Frequency;
import com.lifeonwalden.dsg.constant.HolidayAdjustRule;

import java.util.Date;
import java.util.Optional;

/**
 * 日期序列生成规则
 */
public class DateGenerateRule {
    /**
     * 频率增长步长，一般为1，即每周，每月
     */
    private int step = 1;

    /**
     * 日期序列频率类型
     * <p>
     * 必设置项
     */
    private Frequency frequency = Frequency.WEEK;

    /**
     * 序列的起始日期，包含
     * <p>
     * 必设置项
     */
    private Date start;

    /**
     * 序列的截止日期，包含
     * <p>
     * 必设置项
     */
    private Date end;

    /**
     * 上级频率期间内的某一天
     * 正值为频率期间初始的第几天，负值为频率期间倒数的第几天
     * 其中，周频不支持负值
     * 星期几与数值的对应关系可见 {@link java.time.DayOfWeek DayOfWeek}，为 MONDAY(1) - SUNDAY(7)
     */
    private Optional<Integer> dayOf = Optional.empty();

    /**
     * 上级频率内第几周的周几与第几个周几的开关
     * <p>
     * {@code true} 表示为第几个周几。例如：2022年4月的第一个周一则为2022年4月4日
     * {@code false} 表示为第几周的周几。例如：2022年4月的第一周的周一，不存在；第二周的周一则为2022年4月4日
     */
    private boolean focusOnDayOfWeek = true;

    /**
     * 上级频率期间内的某一周
     * 正值为频率期间初始的第几周，负值为频率期间倒数的第几周
     * 其中，周频不支持该值
     */
    private Optional<Integer> weekOf = Optional.empty();

    /**
     * 频率期间内的某一月
     * 不支持负值
     * 其中，周频、月频不支持该值
     * 月份与数值的对应关系可参见 {@link java.time.Month Month}, 为JANUARY(1) - DECEMBER(12)
     */
    private Optional<Integer> monthOf = Optional.empty();

    /**
     * 遇到节假日时的调整策略
     */
    private HolidayAdjustRule holidayAdjustRule = HolidayAdjustRule.KEEP;

    public int getStep() {
        return step;
    }

    public DateGenerateRule setStep(int step) {
        this.step = step;
        return this;
    }

    public Frequency getFrequency() {
        return frequency;
    }

    public DateGenerateRule setFrequency(Frequency frequency) {
        this.frequency = frequency;
        return this;
    }

    public Date getStart() {
        return start;
    }

    public DateGenerateRule setStart(Date start) {
        this.start = start;
        return this;
    }

    public Date getEnd() {
        return end;
    }

    public DateGenerateRule setEnd(Date end) {
        this.end = end;
        return this;
    }

    public Optional<Integer> getDayOf() {
        return dayOf;
    }

    public DateGenerateRule setDayOf(Optional<Integer> dayOf) {
        this.dayOf = dayOf;
        return this;
    }

    public boolean isFocusOnDayOfWeek() {
        return focusOnDayOfWeek;
    }

    public DateGenerateRule setFocusOnDayOfWeek(boolean focusOnDayOfWeek) {
        this.focusOnDayOfWeek = focusOnDayOfWeek;
        return this;
    }

    public Optional<Integer> getWeekOf() {
        return weekOf;
    }

    public DateGenerateRule setWeekOf(Optional<Integer> weekOf) {
        this.weekOf = weekOf;
        return this;
    }

    public Optional<Integer> getMonthOf() {
        return monthOf;
    }

    public DateGenerateRule setMonthOf(Optional<Integer> monthOf) {
        this.monthOf = monthOf;
        return this;
    }

    public HolidayAdjustRule getHolidayAdjustRule() {
        return holidayAdjustRule;
    }

    public DateGenerateRule setHolidayAdjustRule(HolidayAdjustRule holidayAdjustRule) {
        this.holidayAdjustRule = holidayAdjustRule;
        return this;
    }
}
